/**
 * 操作leveldb数据库
 * @param db  leveldb数据库连接
 * @return {obj} proxy对象
 *    插入数据：         obj.前缀（表名）.put(value,key)
 *    获取单条数据 ：  obj.前缀（表名）.get(key)
 *    删除数据 ：        obj.前缀（表名）.del(key/keyArr)
 *    更新数据 ：        obj.前缀（表名）.update(key.value)
 *    查询数据 ：        obj.前缀（表名）.find(condition,options)
 */

module.exports=  function (db) {
    let interval="!";
    let DB={
       _prefix:'',
        interval:interval,
        prefix:function (prefix) {
            this._prefix=prefix;
        },
        /**
         * 插入数据
         * @param value [JSON]  需插入的值
         * @param key   [String]  插入的键名（默认自动生成）  [可选]
         * @return id     [String]   生成的id
         */
        put:async function (value,key) {
            let prefix=this._prefix;
            if(prefix && Object.prototype.toString.call(value)== '[object Object]'){
                return new Promise(async function (resolve,reject) {
                    let random=key?key:uid();
                    let id=prefix+interval+random;
                    this._prefix="";
                    value._id=random;
                    db.batch([{type: 'put', key: id, value: JSON.stringify(value)},]).then(function () {
                        resolve(id);
                    }).catch(function () {
                        resolve(false);
                    });
                });
            }else{
                resolve(false);
            }
        },

        /**
         * 获取单条数据
         * @param key [String] 数据对应的键名
         * @return res [JSON]   返回查询到的数据或null
         */
        get:async function (key) {
            let prefix=this._prefix;
            let feild=prefix+interval+key;
            this._prefix="";
            if(prefix && key){
                try{
                    let res= await db.get(feild);
                    return JSON.parse(res);
                }catch (e){
                    return null;
                }
            }else return null;
        },

        /**
         * 删除数据
         * @param keyArr  [String/Array] 键名或键名数组
         * @return true/false
         */
        del:async function (keyArr) {
            var self=this;
            if(Object.prototype.toString.call(keyArr) != '[object Array]'){
                keyArr=[keyArr];
            }
            let prefix=this._prefix;
            var tmp=[]
            for(var i=0;i<keyArr.length;i++){
                if(keyArr[i]){
                    tmp.push({ type: 'del', key: prefix+interval+keyArr[i]},)
                }
            }
            return new Promise(async function (resolve) {
                db.batch(tmp,function (err) {
                    self._prefix="";
                    resolve(err?false:true);
                })
            });
        },

        /**更新数据
         * @param key    [String]  键名
         * @param value [JSON]   需要更新值
         * @return true/false
         */
        update:async function(key,value){
            let prefix=this._prefix;
            if(key && value && Object.prototype.toString.call(value) == '[object Object]'){
                let feild=prefix+interval+key;
                this._prefix="";
                return new Promise(async function (resolve,reject) {
                    try {
                        let val= await db.get(feild);
                        val=JSON.parse(val);
                        for(let i in value){
                            val[i]=value[i];
                        }
                        db.batch([
                            {type: 'del', key: feild},
                            {type: 'put', key: feild, value: JSON.stringify(val)},
                        ]).then(function () {
                            resolve(true);
                        }).catch(function () {
                            resolve(false);
                        });
                    }catch (e){
                        resolve(false);
                    }
                });
            }else{
                return false;
            }
        },

        /**
         * 查询数据
         * @param condition [String]  筛选条件，格式类似js条件表达式， et: data.[键值中的字段名] >5 &&  data.[键值中的字段名]==6 ||  data.[键值中的字段名]<=5
         * @param options   [Object]
         *                  {
         *                      sort:{字段名:'排序方式(asc/desc)',字段名:'排序方式(asc/desc)},//排序规则，最多2个字段排序
         *                      limit:[第几页,每页多少条数]//分页规则
         *                  }
         * @return res[Array] 查询结果
         */
        find:async function (condition,options) {
            let prefix=this._prefix;
            if(!prefix)return [];
            return new Promise(function (resolve,reject) {
                let resList=[],data;
                let time2=new Date().getTime();
                eval("function verify(data){return ("+condition+");}");
                db.createReadStream({
                    gte:prefix+interval,
                    lte:prefix+interval+"a",
                }).on('data',function (res) {
                    data=JSON.parse(res.value);
                    //data._id=res.key.split(interval)[1];
                    if(condition){
                        if(verify(data))resList.push(data);
                    }else {
                        resList.push(data);
                    }
                }).on('end',function (e) {
                   //console.log('读取',new Date().getTime()-time2,resList.length);
                    this._prefix="";

                    //排序
                    if(options && options.sort){
                        let time=Date().now;
                        let arr=[];
                        for(let i in options.sort){
                            arr.push(new Array(i,options.sort[i]));
                        }
                        resList.sort(function (a,b) {
                            //console.log(arr[0][0],arr[0][1],arr[1][0],arr[1][1])
                            if(arr[1]){
                                return arrSort(a[arr[0][0]],b[arr[0][0]],arr[0][1],a[arr[1][0]],b[arr[1][0]],arr[1][1])
                            }else{
                                return arrSort(a[arr[0][0]],b[arr[0][0]],arr[0][1])
                            }
                        });
                        console.log('排序',new Date().getTime()-time);
                    }

                    //分页
                    if(options && options.limit){
                        let time=new Date().getTime();
                        let tmp=[];
                        for( let i=0;i<resList.length;i++){
                            if((options.limit[0]-1)*options.limit[1]<=i){
                                tmp.push(resList[i]);
                                if(options.limit[1]<=i)break;
                            }
                        }
                        resList=tmp;
                        console.log('分页',new Date().getTime()-time);
                    }
                    resolve(resList);
                });
            })
        }
    }
    DB.db=db;
    return new Proxy({},{
        get:function (target,key) {
              if(key){
                  if(key=="_DB_")return db;
                  DB.prefix(key)
                  return DB;
              }else{
                  return null;
              }
        }
    });
}

//生成唯一id
function uid() {
   var timeStr=new Date().getTime();
   var random=createRandom()+""+createRandom();
   return timeStr+""+random;
}

function createRandom() {
    return parseInt((Math.random()+1)*1000).toString().substr(1,4);
}

//数组排序
function arrSort(a,b,sortType,a1,b1,sortType1){
    if(a>b){
        return sortType=="desc"?-1:1;
    }else if(a==b){
        if(a1 && b1) {
            return arrSort(a1,b1,sortType1);
        }else{
            return 1;
        }
    }else{
        return sortType=="desc"?1:-1;
    }
}